import copy
from flask import jsonify, request
from mongoengine.errors import ValidationError

from app.libs.redprint import RedPrint
from app.errors import NotFound
from app.db.models.news import News
from app.serializers import SimpleSerializer


api = RedPrint('news')


def update_query(request_args: dict, query=None) -> dict:
    if not query:
        new_query = {}
    else:
        new_query = copy.deepcopy(query)

    if title := request_args.get('title'):
        new_query['title__icontains'] = title
    if _type := request_args.get('type'):
        new_query['type'] = _type
    try:
        if is_consoleDisplay := request_args.get('isConsoleDisplay'):
            new_query['isConsoleDisplay'] = bool(int(is_consoleDisplay))
        if isHomepage_display := request_args.get('isHomepageDisplay'):
            new_query['isHomepageDisplay'] = bool(int(isHomepage_display))
        if is_recommendDisplay := request_args.get('isRecommendDisplay'):
            new_query['isRecommendDisplay'] = bool(int(is_recommendDisplay))
        if is_endNotification := request_args.get('isSendNotification'):
            new_query['isSendNotification'] = bool(int(is_endNotification))
    except ValueError:
        pass

    return new_query


@api.route('/list', methods=['GET'])
def get_news():
    request_args = request.args
    try:
        page = int(request_args.get('page', 1))
        limit = int(request_args.get('limit', 10))
    except ValueError:
        page = 1
        limit = 10

    query = {'isDraft': False}

    query = update_query(request_args, query)

    total_news = News.objects.exclude('content').filter(**query)
    total = total_news.count()
    news = total_news.paginate(page, limit)

    ctx = {
        'code': 200,
        'status': 'success',
        'data': {
            'page': page, 'limit': limit, 'total': total, 'data': [SimpleSerializer(item).data for item in news.items]}
    }

    return jsonify(ctx)


@api.route('/detail', methods=['GET'])
def get_detail():
    request_args = request.args
    _id = request_args.get('id')

    query = {'isDraft': False}
    query = update_query(request_args, query)

    try:
        current = News.objects.filter(pk=_id, **query).first()
    except ValidationError:
        raise NotFound
    if not current:
        raise NotFound
    last = News.objects.only('title', 'id').filter(datetime__gt=current.datetime, **query).order_by('datetime').first()
    next_ = News.objects.only('title', 'id').filter(datetime__lt=current.datetime, **query).first()

    ctx = {
        'code': 200,
        'status': 'success',
        'data': {
            'last': SimpleSerializer(last).data,
            'next': SimpleSerializer(next_).data,
            'current': SimpleSerializer(current).data
        }
    }

    return jsonify(ctx)
